<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2016 yuangaokun
 * @date 2016-11-25
 */

namespace common\widgets;

/**
 * Alert widget renders a message from session flash. All flash messages are displayed
 * in the sequence they were assigned using setFlash. You can set message as following:
 *
 * ```php
 * \Yii::$app->session->setFlash('error', 'This is the message');
 * \Yii::$app->session->setFlash('success', 'This is the message');
 * \Yii::$app->session->setFlash('info', 'This is the message');
 * ```
 *
 * Multiple messages could be set as follows:
 *
 * ```php
 * \Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']);
 * ```
 *
 * @author Kartik Visweswaran <kartikv2@gmail.com>
 * @author Alexander Makarov <sam@rmcreative.ru>
 */
use Yii;
use yii\log\FileTarget;

class Tool extends \yii\bootstrap\Widget
{
    private static $emailPreg = '/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/';
   // private static $phonePreg = '/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[0-9]|18[0|1|2|3|4|5|6|7|8|9])\d{8}$/';
    private static $phonePreg = '/^\d{1,}$/';
    private static $urlPreg = '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?.*$/';
    private static $numPreg = '/(\-|\+)?(([1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(0{1}$)|([0-9]\.[0-9]{1,2}$))/';
    private static $id = '/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)/';
    private static $bankCardNumber = '/^([1-9]{1})(\d{13,20})$/';
    private static $password = '/^[A-Za-z0-9]{6,12}$/';
    private static $positiveNum = '/^[1-9]\d*$/';
    private static $logUsername = '/^[a-z0-9]*$/';

    /**
     * @var array the alert types configuration for the flash messages.
     * This array is setup as $key => $value, where:
     * - $key is the name of the session flash variable
     * - $value is the bootstrap alert type (i.e. danger, success, info, warning)
     */

    /**
     * @var array the options for rendering the close button tag.
     */

    /**
     * @param $arr
     * 打印Array数组
     */
    public static function p($arr){
        echo '<pre>';
        print_r($arr);
        echo '</pre>';
    }

	public static function dateFormat($unixTime)
	{
		return date('Y-m-d H:i:s', $unixTime);
	}

    /**
     * @param $obj
     * @param int $flag
     * 打印最后一条SQL语句
     */
    public static function g($obj,$flag=1){
        if($flag){
            $com = clone $obj;
            echo $com->createCommand()->getRawSql();
        }else{
            $com = clone $obj;
            echo $com->createCommand()->getRawSql();
            die;
        }
    }

    /**
     * 表单数据过滤
     * @param $string
     * @param bool|FALSE $simple
     * @return bool
     */
    public static function  xssFilter(&$string, $simple = FALSE)
    {
        if (!is_array ($string))
        {
            $string = trim ($string);
            $string = htmlspecialchars ($string);
            $string = addslashes($string);
            if ($simple)
            {
                return TRUE;
            }
            $string = strip_tags ($string);
            $string = str_replace (array(
                '"',
                "\\",
                "'",
                "/",
                "..",
                "../",
                "./",
                "//"
            ), '', $string);
            $no = '/%0[0-8bcef]/';
            $string = preg_replace ($no, '', $string);
            $no = '/%1[0-9a-f]/';
            $string = preg_replace ($no, '', $string);
            $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
            $string = preg_replace ($no, '', $string);
            return TRUE;
        }
        $keys = array_keys ($string);
        foreach ($keys as $key)
        {
            self::xssFilter ($string[$key], $simple);
        }
    }

    /**
     * @param $key
     * @param int $time
     * @return int|string
     * @author Lxs
     * 后台频率请求时间限制
     */
    public static function requestDelay($key, $time=5)
    {
        if(Yii::$app->cache->get(md5($key)))
        {
            return '系统繁忙，请稍后重试';
        }
        return Yii::$app->cache->add(md5($key), time(), $time) ? 1 : '系统繁忙，请稍后重试';
    }

    /**
     * @param $email
     * @return bool
     * @author Lxs
     * 邮箱验证
     */
    public static  function isEmail($email)
    {
        if(preg_match(self::$emailPreg, $email))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * @param $phone
     * @return bool
     * @author Lxs
     * 手机号码验证
     */
    public static  function isPhone($phone)
    {
        if(preg_match(self::$phonePreg, $phone))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * @param $url
     * @return bool
     * @author Lxs
     * 链接地址验证
     */
    public static  function isUrl($url)
    {
        if(preg_match(self::$urlPreg, $url))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * @param $url
     * @return bool
     * @author xl
     * 验证是否是正数+0
     */
    public static  function isNum($num)
    {
        if(preg_match(self::$numPreg, $num))
        {
            return TRUE;
        }

        return FALSE;
    }

    /**
     * @param $id
     * @return bool
     * @author Lxs
     * 身份证号验证
     */
    public static  function isId($id)
    {
        if(preg_match(self::$id, $id))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * @param $bankCardNumber
     * @return bool
     * @author Lxs
     * 银行卡号验证
     */
    public static  function isBankCardNumber($bankCardNumber)
    {
        if(preg_match(self::$bankCardNumber, $bankCardNumber))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * 判断是否为密码
     * @param $password
     * @return bool
     * @author Lxs
     */
    public static  function isPassword($password)
    {
        if(preg_match(self::$password, $password))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * 判断是否为正整数
     * @param $positiveNum
     * @return bool
     * @author Lxs
     */
    public static  function isPositiveNum($positiveNum)
    {
        if(preg_match(self::$positiveNum, $positiveNum))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * 是否为登录账号
     * @param $logUsername
     * @return bool
     * @author Lxs
     */
    public static  function isLogUsername($logUsername)
    {
        if(preg_match(self::$logUsername, $logUsername))
        {
            return TRUE;
        }
        return FALSE;
    }

    /**
     * 计算重叠时长
     * @param $time1 array 被比较的数组参数   二维数组 array(
     *                          array(9,10),
     *                          array(13,15),
     *                           array(19,21),
     *                      );
     * @param $time2 array 二维数组 $b=array(
     *                          array(8,16),
     *                         );
     * @return float
     * @created Lxs
     */
    public static function calOverlap($time1, $time2)
    {
        $time = 0;

        foreach($time2 as $v1)
        {
            foreach($time1 as $v2)
            {
                if($v1[0] < $v2[1] && $v1[1] > $v2[0])
                {
                    if($v1[0] <= $v2[0] && $v1[1] <= $v2[1])
                    {
                        $time += $v1[1] - $v2[0];
                    }elseif($v1[0] >= $v2[0] && $v1[1] <= $v2[1])
                    {
                        $time += $v1[1] - $v1[0];
                    }elseif($v1[0] >= $v2[0] && $v1[1] > $v2[1])
                    {
                        $time += $v2[1] - $v1[0];
                    }elseif($v1[0] < $v2[0] && $v1[1] > $v2[1])
                    {
                        $time += $v2[1] - $v2[0];
                    }
                }
            }
        }

        return $time;
    }

    /**
     * 返回数组
     * @param array $data
     * @param int $code
     * @param string $msg
     * @return array
     * @author Lxs
     */
    public static function returnArray($data = [], $code = 200, $msg = '成功')
    {
        return array(
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        );
    }

	/**
	 * 返回json字符串
	 * @param array $data
	 * @param int $code
	 * @param string $msg
	 * @author csj
	 */
	public static function returnJson($data = [], $code = 200, $msg = '成功')
	{
		return json_encode(array(
			'code' => $code,
			'msg' => $msg,
			'data' => $data,
		), JSON_UNESCAPED_SLASHES);
	}


    /**
     * @param $str
     * @return mixed
     * @author YH
     * 过滤emoji
     */
    public static function emojiFilter($str)
    {
        $str = preg_replace_callback(
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);

        return $str;
    }

    /**
     * 创建验证码
     * @author Lxs
     */
    public static function createCode(){

        Yii::$app->session['login_verify_code'] = '';
        //画布
        $img = imagecreatetruecolor(100, 36);

        //字体颜色
        $red =   imagecolorallocate($img, 220, 20, 60);
        $green =   imagecolorallocate($img, 0, 128, 0);
        $blue =   imagecolorallocate($img, 0, 0, 255);
        $pink =   imagecolorallocate($img, 255, 20, 147);
        $black =   imagecolorallocate($img, 0, 0, 0);

        $color_array =[$red, $green, $blue, $pink, $black];

        //显示字符串
        $string = str_shuffle(implode('', array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'))));
        $string = str_split($string, 4)[array_rand(range(0, 14))];


        //背景颜色
        $bg_color = imagecolorallocate($img, 200, 200, 200);

        imagefill($img, 0, 0, $bg_color);


        Yii::$app->session['login_verify_code'] = strtolower($string);
        //画字符串
        imagestring ($img, 5, 20, rand(8, 15), $string{0}, $color_array[array_rand($color_array)]);
        imagestring ($img, 5, 40, rand(8, 15), $string{1}, $color_array[array_rand($color_array)]);
        imagestring ($img, 5, 60, rand(8, 15), $string{2}, $color_array[array_rand($color_array)]);
        imagestring ($img, 5, 80, rand(8, 15), $string{3}, $color_array[array_rand($color_array)]);


        $line_color = imagecolorallocate($img, 120, 120, 120);
        //画干扰线
        imageline($img, rand(8, 15), rand(8, 15), rand(90, 100), rand(8, 15), $line_color);
       // imageline($img, rand(8, 15), rand(15, 20), rand(90, 100), rand(15, 20), $line_color);
        imageline($img, rand(8, 15), rand(20, 30), rand(90, 100), rand(20, 30), $line_color);
        header('content-type:image/png');
        imagepng($img);
        imagedestroy($img);
        exit;
    }

    /**
     * 简单字符串过滤
     * simple string filter
     * @param $s
     * @param $strict
     * @return string
     * @author Lxs
     */
    public static function sF($s, $strict = FALSE)
    {
        $s = htmlspecialchars(trim($s));
        if($strict){
            $s = str_replace(' ', '', $s);
        }
        return $s;
    }

    /**
     * 根据月份和日期计算星座
     * @param $month
     * @param $day
     * @return string
     * @author Lxs
     */
    public static function getStarMonthAndDay($month, $day)
    {
        $result = '';
//    if (strlen($idCardNumber) == 18) {
//        $month = substr($idCardNumber, 10, 2);
//        $day = substr($idCardNumber, 12, 2);
//    } else {
//        $month = substr($idCardNumber, 8, 2);
//        $day = substr($idCardNumber, 10, 2);
//    }

        if (($month == 1 && $day >= 20) || ($month == 2 && $day <= 18))
        {
            $result = '水瓶座';
        } elseif (($month == 2 && $day >= 19) || ($month == 3 && $day <= 20))
        {
            $result = '双鱼座';
        } elseif (($month == 3 && $day > 20) || ($month == 4 && $day <= 19))
        {
            $result = '白羊座';
        } elseif (($month == 4 && $day >= 20) || ($month == 5 && $day <= 20))
        {
            $result = '金牛座';
        } elseif (($month == 5 && $day >= 21) || ($month == 6 && $day <= 21))
        {
            $result = '双子座';
        } elseif (($month == 6 && $day > 21) || ($month == 7 && $day <= 22))
        {
            $result = '巨蟹座';
        } elseif (($month == 7 && $day > 22) || ($month == 8 && $day <= 22))
        {
            $result = '狮子座';
        } elseif (($month == 8 && $day >= 23) || ($month == 9 && $day <= 22))
        {
            $result = '处女座';
        } elseif (($month == 9 && $day >= 23) || ($month == 10 && $day <= 23))
        {
            $result = '天秤座';
        } elseif (($month == 10 && $day > 23) || ($month == 11 && $day <= 22))
        {
            $result = '天蝎座';
        } elseif (($month == 11 && $day > 22) || ($month == 12 && $day <= 21))
        {
            $result = '射手座';
        } elseif (($month == 12 && $day > 21) || ($month == 1 && $day <= 19))
        {
            $result = '魔羯座';
        }

        return $result;
    }

    /**
     * 获取当前IP地址
     * @param int $type
     * @param bool|false $adv
     * @return mixed
     * @author Lxs
     */
    public static  function getClientIp($type = 0,$adv = false) {
        $type = $type ? 1 : 0;
        static $ip  =  NULL;
        if ($ip !== NULL)
        {
            return $ip[$type];
        }
        if ($adv)
        {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
            {
                $arr  = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                $pos  = array_search('unknown',$arr);
                if(false !== $pos)
                {
                    unset($arr[$pos]);
                }
                $ip  = trim($arr[0]);
            }elseif (isset($_SERVER['HTTP_CLIENT_IP']))
            {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            }elseif (isset($_SERVER['REMOTE_ADDR']))
            {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        }elseif (isset($_SERVER['REMOTE_ADDR']))
        {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = sprintf("%u", ip2long($ip));
        $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);

        return $ip[$type];
    }

    /**
     * 销毁数组某些键
     * @param $data
     * @param $attributes
     * @author Lxs
     */
    public static function unsetArrayAttributes(&$data, $attributes)
    {
        foreach($attributes as $attribute)
        {
            if(isset($data[$attribute]) || array_key_exists($attribute, $data))
            {
                unset($data[$attribute]);
            }
        }
    }

    /**
     * 处理无限极分类数据
     * @param $data
     * @param int $id
     * @return array
     * @author Lxs
     */
   public static function unlimitedClassification($data, $id = 0)
   {
        static $sons=array();

        foreach($data as $v){
            if($v['parentId'] == $id){
                $sons[] = $v;
                self::unlimitedClassification($data, $v['id']);
            }
        }

        return $sons;
    }

    /**
     * 组装无限极分类数据的-tree
     * @param $items
     * @param $pidName
     * @param $idName
     * @return array
     * @author Lxs
     */
   public static function generateTree($items,$pidName,$idName)
   {
        foreach($items as $item){
            $items[$item[$pidName]]['children'][$item[$idName]] = &$items[$item[$idName]];
        }

        return isset($items[0]['children']) ? $items[0]['children'] : array();
   }


   /**
     * 处理部门数据
     * @param $data
     * @author Lxs
    */

   public static function dealArray(&$data){
        if(is_array($data)){
            foreach($data as $k => $v)
            {
                if($k == 'children'){
                    if(isset($data['children']) && $data['children']){
                     sort($data['children']);
                   }
                }
                if(is_array($data[$k])){
                    self::dealArray($data[$k]);
                }
            }
        }
   }

   /**
     * 根据部门id获取该部门以及这部门下的所有子部门id数组
     * @param $departments_dict
     * @param $department_id
     * @param array $department_ids
     * @return array
     * @author Lxs
     */

   public static function getDepartments($departments_dict, $department_id, &$department_ids = [])
   {
        if(!$department_id){
            return [];
        }
        if(isset($departments_dict[$department_id]) && $departments_dict[$department_id]['parent_id'] == 0){
            return array_keys($departments_dict);
        }
        $department_ids[] = $department_id;
        foreach($departments_dict as $k => $item){
            if($item['parent_id'] == $department_id){
                unset($departments_dict[$k]);
                self::getDepartments($departments_dict, $item['id'],$department_ids);
            }
        }

        return $department_ids;
   }

    /**
     * 将二维数组按照多个字段依次排序 如 $arr = Tool:: sortByMultiField($array1,'id',SORT_DESC,'age',SORT_DESC);
     * @return mixed|null
     *  @author Hb
     */
    public static function sortByMultiField(){
        $args = func_get_args();
        if(empty($args)){
            return null;
        }

        $arr       = array_shift($args);
        $args_test = array();
        foreach($args as $key => $value){
            if(is_string($value)){
                $temp = array();
                foreach($arr as $k => $v){
                    $temp[$k] = $v[$value];
                }

                $args[$key] = $temp;
            }
        }

        //引用值
        $args[] = &$arr;
        call_user_func_array('array_multisort', $args);
        return array_pop($args);
    }

    /**
     * 输出跟踪日志
     * /APITeacher/runtime/logs/  本地
     * /var/www/html/APITeacher/runtime/logs/ dev
     * /var/www/pre/APITeacher/runtime/logs/  pre
     * @param $data
     * @param string $logName
     * @author Hb
     */
    public static function traceLog($data,$isJson = false,$logName = 'teacher')
    {
        $log = new FileTarget();
        $logName =  Yii::$app->getRuntimePath() . '/logs/error_'.$logName.'.log';
        $data = $isJson ? json_encode($data,JSON_UNESCAPED_SLASHES) : $data;
        $log->logFile = $logName;
        $log->messages[] = [print_r($data, true), 1, $logName, time()];
        $log->export();
    }

    /**
     * 随机生成几位字符串
     * @author xl
     * @param $length
     * @return string
     */
    public static function getRandStr($length)
    {
        $str = '';
        $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($str_pol) - 1;
        for ($i = 0; $i < $length; $i++) {
            $str .= $str_pol[mt_rand(0, $max)];
        }
        return $str;
    }

    /**
     * 组装分页信息
     * @param int $page
     * @param int $limit
     * @return array
     * @author Hb
     */
    public static function buildPages($page = 1,$limit = 8)
    {
        return [
            'page_num' => max(1,intval($page)),
            'limit' => max(0,intval($limit)),
        ];
    }

    /**
     * 格式化字符串
     * @param $num
     * @param int $digit 保留的小数位数
     * @return string
     * @author Hb
     */
    public static function formatNum($num,$digit = 2)
    {
        $digit = max(0,$digit);
        return sprintf('%.' . $digit .'f',$num);
    }

}
